package com.hfb.mashibing.alip8.interview.juc;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class ForkJoinTaskExample extends RecursiveTask<Long> {
    public static final int threshold = 2;
    private int start;
    private int end;
    public ForkJoinTaskExample(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        Long sum= 0L;
        // 如果任务足够小，就 计算任务
        boolean conComadde = (end - start) <= threshold;
        if(conComadde) {
            for (int i = start; i <= end; i++) {
                sum += i;
            }
        } else {
            // 若是任务大于阀值，就分裂成2个子任务计算
            int middle = (start+end) / 2;
            ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);
            ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle+1, end);

            // 执行子任务
            leftTask.fork();
            rightTask.fork();
            // 等待并接收返回值
            Long leftJoin = leftTask.join();
            Long rightJoin = rightTask.join();
            // 合并结果
            sum = leftJoin + rightJoin;
        }

        return sum;
    }




    public static void main(String[] args) {
        int start = 1;
        List<Integer> ends = new ArrayList<Integer>(){{
            add(0,10);
            add(1,100);
            add(2,1000);
            add(3,1000_0);
            add(4,1000_00);
            add(5,1000_000);
            add(6,1000_000_0);
            add(7,1000_000_00);
            add(8,1000_000_000);
            add(9,Integer.MAX_VALUE);
        }};

        System.err.println("===========================");
        ends.forEach(end -> {
            long s = System.currentTimeMillis();

            ForkJoinPool forkJoinPool = new ForkJoinPool();
            // 生成一个计算任务
            ForkJoinTaskExample task = new ForkJoinTaskExample(start, end);
            // 执行一个任务
            ForkJoinTask<Long> result = forkJoinPool.submit(task);

            try {
                System.out.printf("{%s%s}, cost:%s ms\n",
                                  start + "+..." + end + " = ",
                                  result.get(),
                                  (System.currentTimeMillis()-s));

                System.err.println("===========================");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
        System.err.println("======关注点：任务量与时间的关系====");
    }

}
